package com.yiba.vpn.protocal;

import com.yiba.logutils.LogUtils;
import com.yiba.vpn.VPNServiceManager;
import com.yiba.vpn.core.LocalVpnService;
import com.yiba.vpn.utils.CommonMethods;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 测试VPN端口是否可用，并且拿到端口的流量
 * Created by Administrator on 2017/11/16 0016.
 */

public class DBQTestTimeDelay{
    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
    private String entranceIp;//服务器IP
    public static int port;//端口
    public static long aPartDealy; //vpn端口出入时延
    private String portFlowSpeed; //端口流量
    public static boolean IsRunning = false;
    public int count;//计数

    public DBQTestTimeDelay(String entranceIp, int port) {
        LogUtils.getInstance().log(VPNServiceManager.TAG,"VPN开始端口检测: ");
        this.entranceIp = entranceIp;
        this.port = port;
        IsRunning = true;
    }

    Runnable runnable_udp = new Runnable() {

        @Override
        public void run() {
            if (IsRunning&&count<10) {
                DatagramSocket tempClientSocket = null;
                try {
                    tempClientSocket = new DatagramSocket(0);
                    tempClientSocket.setSoTimeout(2000);
                } catch (SocketException e) {
                    e.printStackTrace();
                    LogUtils.getInstance().log(VPNServiceManager.TAG,"VPN端口检测异常_发送数据包: "+e.getMessage());
                }
                SocketAddress inetSocketAddress = new InetSocketAddress(CommonMethods.ipIntToInet4Address
                        (CommonMethods.ipStringToInt(entranceIp)), 22222);
                //                    (CommonMethods.ipStringToInt(entranceIp)), 22222);
                //            DBQPacket dbqPacket = new DBQPacket();
                //            dbqPacket.Header.type = 100;
                //            dbqPacket.data = "{\"port\":"+port+"}";
                //            dbqPacket.Header.tLength = dbqPacket.data.length() + 8;
                //            ByteBuffer buf = ByteBuffer.allocate(1000);
                //            dbqPacket.toBytes(buf);
                //            buf.limit(dbqPacket.Header.tLength);
                String data = Integer.toString(port);
                DatagramPacket datagramPacket = new DatagramPacket(data.getBytes(), 0, data.getBytes().length);
                datagramPacket.setSocketAddress(inetSocketAddress);
                long sendTime = System.currentTimeMillis();
                try {
                    if (LocalVpnService.Instance == null || !LocalVpnService.Instance.protect(tempClientSocket)) {
                        tempClientSocket.send(datagramPacket);
                    } else {
                        tempClientSocket.send(datagramPacket);
                    }
                } catch (IOException e3) {
                    e3.printStackTrace(System.err);
                }

                try {
                    byte[] RECEIVE_BUFFER = new byte[2000];
                    //                new IPHeader(RECEIVE_BUFFER, 0).Default();
                    //                UDPHeader uDPHeader = new UDPHeader(RECEIVE_BUFFER, 20);
                    //                ByteBuffer lonlifeBuffer = ByteBuffer.wrap(RECEIVE_BUFFER);
                    //                lonlifeBuffer.position(28);
                    //                lonlifeBuffer = lonlifeBuffer.slice();
                    datagramPacket = new DatagramPacket(RECEIVE_BUFFER, 0, RECEIVE_BUFFER.length);
                    //                datagramPacket.setLength(RECEIVE_BUFFER.length - 28);
                    tempClientSocket.receive(datagramPacket);
                    int length = datagramPacket.getLength();//获取后台的数据ok_12000: 端口UP 流量12000字节
                    //                lonlifeBuffer.clear();
                    //                lonlifeBuffer.limit(datagramPacket.getLength());
                    //                DBQPacket lonlifePacket = DBQPacket.fromBytes(lonlifeBuffer);
                    //datagramPacket.getData();
                    String result = new String(datagramPacket.getData(), "UTF-8");
                    if(result.substring(0,length).length()!=2) {
                        String[] real_result = result.substring(0, length).split("_");
                        LogUtils.getInstance().log(VPNServiceManager.TAG, "VPN端口检测获取后台的心跳包: " + "端口：" + real_result[0] + "===>" + "流量：" + real_result[1]);
                        if ("ok".equals(real_result[0])) {
                            long receivedTime = System.currentTimeMillis();
                            DBQTestTimeDelay.this.aPartDealy = receivedTime - sendTime;
                            DBQTestTimeDelay.this.portFlowSpeed = real_result[1];
                            LogUtils.getInstance().log(VPNServiceManager.TAG, "VPN端口检测获取后台的心跳包时延为: " + aPartDealy + "ms");
                        }
                    }else {
                        String real_result_error = result.substring(0, length);
                        if ("no".equals(real_result_error)) {
                            count ++;
                            //端口down
                            if(count>10)
                            IsRunning = false;
                            LogUtils.getInstance().log(VPNServiceManager.TAG, "VPN端口检测不正常: ");
                        }
                    }
                } catch (Exception e) {
                    count ++;
                    e.printStackTrace(System.err);
                    LogUtils.getInstance().log(VPNServiceManager.TAG,"VPN端口检测异常_接收数据包: "+e.getMessage());
                }
            }
        }
    };

    /**
     * 开启测试
     */
    public void start_UDP_TimeDelay() {
        this.scheduledExecutorService.scheduleWithFixedDelay(this.runnable_udp, 0, 1, TimeUnit.SECONDS);
    }

    /**
     * 关闭测试
     */
    public void stop_UDP_TimeDelay() {
        if (this.scheduledExecutorService != null) {
            this.scheduledExecutorService.shutdown();
        }
    }

    public String getPortFlowSpeed() {
        return portFlowSpeed;
    }

    public long getaPartDealy() {
        return aPartDealy;
    }
}
